package simplescenegraph.assets.models.obj;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import simplescenegraph.Material;
import simplescenegraph.Node;
import simplescenegraph.Renderer;
import simplescenegraph.SceneObject;
import simplescenegraph.math.Vector2f;
import simplescenegraph.math.Vector3f;

public class OBJModel extends SceneObject {
	
	private static final String DEFAULT_GROUP_NAME = "default";
	
	public static final String DEFAULT_MATERIAL_NAME = "default";
	
	private String name;
	
	private List<Vector3f> positions = new ArrayList<Vector3f>();
	
	private List<Vector3f> normals = new ArrayList<Vector3f>();
	
	private List<Vector2f> uvCoordinates = new ArrayList<Vector2f>();
	
	private Map<String, Material> materials = new HashMap<String, Material>();
	
	private List<OBJGroup> groups = new ArrayList<OBJGroup>();
	
	private boolean useTexture = true;

	public OBJModel() {
		boundingVolume = null;
		
		addGroup(new OBJGroup(this, DEFAULT_GROUP_NAME));
		addMaterial(new Material(DEFAULT_MATERIAL_NAME));
	}
	
	@Override
	public void setLeafNode(Node leafNode) {
		super.setLeafNode(leafNode);
		
		for (OBJGroup group : groups) {
			group.updateLeafNode();
		}
	}
	
	public String getName() {
		return name;
	}

	public boolean isTextureEnabled() {
		return useTexture;
	}

	public void enableTexture(boolean enableTexture) {
		useTexture = enableTexture;
		
		for (Material material :  materials.values()) {
			material.enableTexture(useTexture);
		}
	}
	
	public void prepare(boolean calculateVertexesNormals) {
		for (OBJGroup group : groups) {
			group.prepare(calculateVertexesNormals);
		}
	}

	public Material getMaterial(String materialName) {
		if (materialName == null) {
			throw new IllegalArgumentException();
		}
		
		return materials.get(materialName);
	}

	public OBJGroup getDefaultGroup() {
		return groups.get(0);
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public void draw(Renderer renderer) {
		for (OBJGroup group : groups) {
			group.draw(renderer);
		}
	}

	public void addGroup(OBJGroup group) {
		if (group == null) {
			throw new IllegalArgumentException();
		}
		
		groups.add(group);
	}
	
	public void addMaterial(Material material) {
		if (material == null) {
			throw new IllegalArgumentException();
		}
		
		materials.put(material.getName(), material);
	}

	public void addPosition(Vector3f position) {
		if (position == null) {
			throw new IllegalArgumentException();
		}
		
		positions.add(position);
	}

	public void addNormal(Vector3f normal) {
		if (normal == null) {
			throw new IllegalArgumentException();
		}
		
		normals.add(normal);
	}

	public void addUVCoordinate(Vector2f uvCoordinate) {
		if (uvCoordinate == null) {
			throw new IllegalArgumentException();
		}
		
		uvCoordinates.add(uvCoordinate);
	}

	public void addMaterials(List<Material> materials) {
		if (materials == null) {
			throw new IllegalArgumentException();
		}
		
		for (Material material : materials) {
			addMaterial(material);
		}
	}

	public Vector3f getPositionByIndex(int index) {
		if (index < 0) {
			throw new IllegalArgumentException();
		}
		
		return positions.get(index);
	}

	public Vector3f getNormalByIndex(int index) {
		if (index < 0) {
			throw new IllegalArgumentException();
		}
		
		return normals.get(index);
	}

	public Vector2f getUVCoordinateByIndex(int index) {
		if (index < 0) {
			throw new IllegalArgumentException();
		}
		
		return uvCoordinates.get(index);
	}
	
}
 
